package main

import (
	"log"
	"os"
	"solargis/config"
	"solargis/logging"
	"solargis/model/requestModel"
	"solargis/task"
	"strconv"
	"time"

	// 添加Windows服务支持包
	"golang.org/x/sys/windows/svc"
	"golang.org/x/sys/windows/svc/debug"
)

const defaultConfigPath = "config/config.yaml"

func init() {
	// 初始化日志系统
	if err := logging.Init(); err != nil {
		log.Printf("日志系统初始化失败: %v", err)
	}

	configPath := getConfigPath()
	_, err := config.LoadConfig(configPath)
	if err != nil {
		log.Printf("加载配置失败: %v", err)
	}
}

func getConfigPath() string {
	// 从环境变量中获取配置文件路径
	path := os.Getenv("SOLARGIS_CONFIG_PATH")
	if path == "" {
		return defaultConfigPath
	}
	return path
}

// 主函数修改为支持服务模式
func main() {
	isIntSrv, err := svc.IsWindowsService()
	if err != nil {
		logging.Warning.Printf("无法确定我们是否在服务模式下运行: %v", err)
	}
	if isIntSrv {
		// 作为Windows服务运行
		logging.Info.Println("作为Windows服务运行")
		runService()
	} else {
		// 作为普通程序运行
		logging.Info.Println("作为普通程序运行")
		runApplication()
	}
}

func runService() {
	// 使用debug包运行服务
	err := debug.Run("SolarGIS", &solargisService{})
	if err != nil {
		logging.Error.Printf("服务运行失败: %v", err)
		return
	}
}

func runApplication() {
	getConfig := config.GetConfig()
	if getConfig == nil {
		logging.Error.Fatal("配置获取失败，程序退出")
		return
	}

	// 启动定时任务
	startTimers(getConfig)
}

// Windows服务结构体
type solargisService struct{}

func (m *solargisService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
	const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
	changes <- svc.Status{State: svc.StartPending}

	// 启动应用程序逻辑
	go func() {
		getConfig := config.GetConfig()
		if getConfig != nil {
			startTimers(getConfig)
		}
	}()

	changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}

loop:
	for {
		select {
		case c := <-r:
			switch c.Cmd {
			case svc.Interrogate:
				changes <- c.CurrentStatus
			case svc.Stop, svc.Shutdown:
				// 服务停止逻辑
				logging.Info.Println("服务正在停止")
				break loop
			default:
				continue loop
			}
		}
	}

	changes <- svc.Status{State: svc.StopPending}
	return
}

func currentRequest(getConfig *config.Config) {
	data, err := requestModel.BuildDailyRequest(getConfig, getConfig.API.Today.Value)
	if err != nil {
		logging.Error.Printf("构建当日请求失败: %v", err)
	}
	logging.Info.Printf("构建当日请求成功:%v", string(data))
	task.Request(string(data), getConfig.API.Today.Key, getConfig.File.Path, getConfig.API.Today.Value, getConfig.File.Separator, getConfig.File.SeparatorValue)
}

func futureRequest(getConfig *config.Config) {
	data, err := requestModel.BuildDailyRequest(getConfig, getConfig.API.FutureDay.Value)
	if err != nil {
		logging.Error.Printf("构建未来请求失败: %v", err)
	}
	logging.Info.Printf("构建未来请求成功%v", string(data))
	task.Request(string(data), getConfig.API.FutureDay.Key, getConfig.File.Path, getConfig.API.FutureDay.Value, getConfig.File.Separator, getConfig.File.SeparatorValue)
}

func startTimers(getConfig *config.Config) {
	// currentRequest 定时器：每10分钟执行一次
	go func() {
		var intervalMinutes int
		if getConfig.API.Today.Cron != "" {
			var err error
			intervalMinutes, err = strconv.Atoi(getConfig.API.Today.Cron)
			if err != nil {
				logging.Warning.Printf("解析定时器间隔失败，使用默认值15分钟: %v", err)
				intervalMinutes = 15
			}
		} else {
			intervalMinutes = 15 // 默认10分钟
		}

		interval := time.Duration(intervalMinutes) * time.Minute
		print("intervalMinutes:", intervalMinutes)
		// 计算下一个整点时间
		now := time.Now()
		next := now.Truncate(interval).Add(interval)
		duration := next.Sub(now)

		// 添加安全检查，避免过长的等待时间
		if duration > 1*time.Hour {
			logging.Warning.Printf("计算的等待时间过长: %v，使用默认间隔", duration)
			duration = interval
			next = now.Add(duration)
		}

		logging.Info.Printf("当前时间: %v, 下次执行时间: %v, 等待时间: %v",
			now.Format("2006-01-02 15:04:05"),
			next.Format("2006-01-02 15:04:05"),
			duration)

		// 等待到整点时间
		time.Sleep(duration)

		currentRequest(getConfig)
		ticker := time.NewTicker(interval)

		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				currentRequest(getConfig)
			}
		}
	}()

	// futureRequest 定时器：每天4次（00:00, 06:00, 12:00, 18:00）
	go func() {
		for {
			now := time.Now()
			nextRun := getNextRunTime(now)
			duration := nextRun.Sub(now)

			logging.Info.Printf("下次 futureRequest 执行时间: %v", nextRun)

			<-time.After(duration)
			futureRequest(getConfig)
		}
	}()

	// 阻塞主程序，保持定时器运行
	select {}
}

func getNextRunTime(now time.Time) time.Time {
	// 设定今天的起始时间
	today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())

	// 定义执行时间点（小时）
	runHours := []int{0, 6, 12, 18}

	// 查找下一个执行时间
	for _, hour := range runHours {
		runTime := today.Add(time.Duration(hour) * time.Hour)
		if runTime.After(now) {
			return runTime
		}
	}

	// 如果今天的时间点都已过，则返回明天的第一个时间点
	return today.Add(24 * time.Hour)
}
